﻿// -------------------------------------------------------------------------
//    @FileName         :    NFOnlinePlayerModule.cpp
//    @Author           :    gaoyi
//    @Date             :    2025-02-27
//    @Email			:    445267987@qq.com
//    @Module           :    NFOnlinePlayerModule
//
// -------------------------------------------------------------------------

#include "NFOnlinePlayerModule.h"

#include <NFOnlineAcc.h>
#include <NFOnlineAccMgr.h>

#include "NFOnlineRole.h"
#include "NFOnlineRoleService.h"
#include "NFStorageBagOpMgr.h"
#include "proto_svr_bag.pb.h"
#include "proto_svr_common.nanopb.h"
#include "DescStore/BagDesc.h"
#include "NFLogicCommon/BagPage/NFBagPageGrid.h"
#include "NFLogicCommon/BagPage/NFBagPageOp.h"
#include "NFServerComm/NFServerCommon/NFIServerMessageModule.h"

NFOnlinePlayerModule::NFOnlinePlayerModule(NFIPluginManager* p) : NFMMODynamicModule(p)
{
}

NFOnlinePlayerModule::~NFOnlinePlayerModule()
{
}

int NFOnlinePlayerModule::Awake()
{
    NFServerConfig* pConfig = FindModule<NFIConfigModule>()->GetAppConfig(NF_ST_ONLINE_SERVER);
    CHECK_NULL_RE_VAL(0, pConfig, false);

    /////////////////role//////////////////////////////////////////////////////////
    RegisterServerMessage(NF_ST_ONLINE_SERVER, E_ZONE2ONLINE_LOGIN_REQ);
    RegisterServerMessage(NF_ST_ONLINE_SERVER, E_ZONE2ONLINE_CREATEROLE_REQ);
    RegisterServerMessage(NF_ST_ONLINE_SERVER, E_ZONE2ONLINE_GETROLE_REQ);
    RegisterServerMessage(NF_ST_ONLINE_SERVER, E_ZONE2ONLINE_LOGIN_END_NTF);
    RegisterServerMessage(NF_ST_ONLINE_SERVER, E_SS_ONLINE_ROLE_REGISTER_NTF);
    RegisterServerMessage(NF_ST_ONLINE_SERVER, E_SS_ONLINE_ROLE_SYNC_NTF);
    RegisterServerMessage(NF_ST_ONLINE_SERVER, E_SS_ONLINE_ROLE_EXIT_NTF);

    ////////////////////////bag////////////////////////////
    RegisterServerMessage(NF_ST_ONLINE_SERVER, E_SS_ONLINE_ROLE_ARRANGE_BAG);
    RegisterServerMessage(NF_ST_ONLINE_SERVER, E_SS_ONLINE_ROLE_BUY_BAG_GRID_PRE);
    RegisterServerMessage(NF_ST_ONLINE_SERVER, E_SS_ONLINE_ROLE_BUY_BAG_GRID);

    RegisterServerMessage(NF_ST_ONLINE_SERVER, E_SS_ONLINE_ROLE_STORAGE_SAVE_PRE);
    RegisterServerMessage(NF_ST_ONLINE_SERVER, E_SS_ONLINE_ROLE_STORAGE_SAVE);

    RegisterServerMessage(NF_ST_ONLINE_SERVER, E_SS_ONLINE_ROLE_PICK_FROM_STORAGE_PRE);
    RegisterServerMessage(NF_ST_ONLINE_SERVER, E_SS_ONLINE_ROLE_PICK_FROM_STORAGE);

    return 0;
}

int NFOnlinePlayerModule::Tick()
{
    return NFIModule::Tick();
}

int NFOnlinePlayerModule::OnDynamicPlugin()
{
    return NFIModule::OnDynamicPlugin();
}

int NFOnlinePlayerModule::OnExecute(uint32_t serverType, uint32_t nEventID, uint32_t bySrcType, uint64_t nSrcID, const google::protobuf::Message* pMessage)
{
    return 0;
}

int NFOnlinePlayerModule::OnHandleClientMessage(uint64_t unLinkId, NFDataPackage& packet)
{
    if (!m_pObjPluginManager->IsInited(NF_ST_ONLINE_SERVER))
    {
        NFLogError(NF_LOG_DEFAULT, packet.nParam1, "Online Server not inited, drop client msg:{}", packet.ToString());
        return -1;
    }

    if (m_pObjPluginManager->IsServerStopping())
    {
        NFLogError(NF_LOG_DEFAULT, packet.nParam1, "Online Server is Stopping, drop client msg:{}", packet.ToString());
        return -1;
    }


    switch (packet.nMsgId)
    {
        default:
        {
            NFLogError(NF_LOG_DEFAULT, 0, "Client MsgId:{} Register, But Not Handle, Package:{}", packet.nMsgId, packet.ToString());
            break;
        }
    }
    return 0;
}

int NFOnlinePlayerModule::OnHandleServerMessage(uint64_t unLinkId, NFDataPackage& packet)
{
    if (!m_pObjPluginManager->IsInited(NF_ST_ONLINE_SERVER))
    {
        NFLogError(NF_LOG_DEFAULT, packet.nParam1, "Online Server not inited, drop client msg:{}", packet.ToString());
        return -1;
    }

    if (m_pObjPluginManager->IsServerStopping())
    {
        NFLogError(NF_LOG_DEFAULT, packet.nParam1, "Online Server is Stopping, drop client msg:{}", packet.ToString());
        return -1;
    }

    int iRetCode = 0;
    switch (packet.nMsgId)
    {
        case E_ZONE2ONLINE_LOGIN_REQ:
        {
            iRetCode = OnHandleAccOnlineLoginReq(unLinkId, packet);
            break;
        }
        case E_ZONE2ONLINE_CREATEROLE_REQ:
        {
            iRetCode = OnHandleAccCreateRoleReq(unLinkId, packet);
            break;
        }
        case E_ZONE2ONLINE_GETROLE_REQ:
        {
            iRetCode = OnHandleAccGetRole(unLinkId, packet);
            break;
        }
        case E_ZONE2ONLINE_LOGIN_END_NTF:
        {
            iRetCode = OnHandleLoginEndNtf(unLinkId, packet);
            break;
        }
        case E_SS_ONLINE_ROLE_REGISTER_NTF:
        {
            iRetCode = OnHandleRoleRegisterNtf(unLinkId, packet);
            break;
        }
        case E_SS_ONLINE_ROLE_SYNC_NTF:
        {
            iRetCode = OnHandleRoleSyncNtf(unLinkId, packet);
            break;
        }
        case E_SS_ONLINE_ROLE_EXIT_NTF:
        {
            iRetCode = OnHandleRoleExitNtf(unLinkId, packet);
            break;
        }
        case E_SS_ONLINE_ROLE_ARRANGE_BAG:
        {
            iRetCode = OnHandleRoleArrangeBag(unLinkId, packet);
            break;
        }
        case E_SS_ONLINE_ROLE_BUY_BAG_GRID_PRE:
        {
            iRetCode = OnHandleRoleBuyBagGridPre(unLinkId, packet);
            break;
        }
        case E_SS_ONLINE_ROLE_BUY_BAG_GRID:
        {
            iRetCode = OnHandleRoleBuyBagGrid(unLinkId, packet);
            break;
        }
        case E_SS_ONLINE_ROLE_STORAGE_SAVE_PRE:
        {
            iRetCode = OnHandleRoleStorageSavePre(unLinkId, packet);
            break;
        }
        case E_SS_ONLINE_ROLE_STORAGE_SAVE:
        {
            iRetCode = OnHandleRoleStorageSave(unLinkId, packet);
            break;
        }
        case E_SS_ONLINE_ROLE_PICK_FROM_STORAGE_PRE:
        {
            iRetCode = OnHandleRolePickFromStoragePre(unLinkId, packet);
            break;
        }
        case E_SS_ONLINE_ROLE_PICK_FROM_STORAGE:
        {
            iRetCode = OnHandleRolePickFromStorage(unLinkId, packet);
            break;
        }
        default:
        {
            NFLogError(NF_LOG_DEFAULT, 0, "Server MsgId:{} Register, But Not Handle, Package:{}", packet.nMsgId, packet.ToString());
            break;
        }
    }
    return iRetCode;
}

int NFOnlinePlayerModule::OnHandleAccOnlineLoginReq(uint64_t unLinkId, NFDataPackage& packet)
{
    proto_ff::Proto_Zone2OnLineLoginReq req;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, req);

    int iRetCode = 0;
    do
    {
        NFOnlineAcc* pOnlineAcc = NFOnlineAccMgr::Instance()->FindOnlineAcc(req.zone_id(), req.player_uin());
        if (!pOnlineAcc)
        {
            pOnlineAcc = NFOnlineAccMgr::Instance()->CreateOnlineAcc(req.zone_id(), req.player_uin());
            if (!pOnlineAcc)
            {
                LOG_ERR(req.player_uin(), -1, "Create OnlineAcc Failed, zoneId:{}, playerUin:{}", req.zone_id(), req.player_uin());
                iRetCode = ERR_CODE_LOGIN_REACH_MAX_NUM;
                break;
            }
        }

        iRetCode = pOnlineAcc->TryAccLogin(req, packet.nSrcId, packet.nParam1);
    }
    while (false);

    if (iRetCode != 0)
    {
        ProcAccLoginErrRes(req, iRetCode, packet.nParam1, packet.nSrcId);
    }
    return 0;
}

int NFOnlinePlayerModule::OnHandleAccCreateRoleReq(uint64_t unLinkId, NFDataPackage& packet)
{
    proto_ff::Proto_Zone2OnLineCreateRoleReq req;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, req);

    int iRetCode = 0;
    do
    {
        NFOnlineAcc* pOnlineAcc = NFOnlineAccMgr::Instance()->FindOnlineAcc(req.zone_id(), req.player_uin());
        if (!pOnlineAcc)
        {
            LOG_ERR(req.player_uin(), -1, "OnlineAcc not found, zoneId:{}, playerUin:{}", req.zone_id(), req.player_uin());
            iRetCode = -1;
            break;
        }

        iRetCode = pOnlineAcc->TryCreateRole(req, packet.nSrcId, packet.nParam1);
    }
    while (false);

    if (iRetCode != 0)
    {
        proto_ff::Proto_OnLine2ZoneCreateRoleRes res;
        res.set_zone_id(req.zone_id());
        res.set_player_uin(req.player_uin());
        res.set_result(iRetCode);

        FindModule<NFIServerMessageModule>()->SendTransToLogicServer(NF_ST_ONLINE_SERVER, packet.nSrcId, E_ONLINE2ZONE_LOGIN_RES, res, req.player_uin(), 0, packet.nParam1);
        return 0;
    }
    return 0;
}

int NFOnlinePlayerModule::OnHandleAccGetRole(uint64_t unLinkId, NFDataPackage& packet)
{
    proto_ff::Proto_Zone2OnlineGetRoleReq req;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, req);

    proto_ff::Proto_Online2ZoneGetRoleRes res;
    res.set_zone_id(req.zone_id());
    res.set_player_uin(req.player_uin());
    res.set_role_id(req.role_id());

    int iRetCode = 0;
    do
    {
        NFOnlineAcc* pOnlineAcc = NFOnlineAccMgr::Instance()->FindOnlineAcc(req.zone_id(), req.player_uin());
        if (!pOnlineAcc)
        {
            LOG_ERR(req.role_id(), -1, "OnlineAcc not found, zoneId:{}, playerUin:{}", req.zone_id(), req.player_uin());
            iRetCode = -1;
            break;
        }

        auto pRoleOne = pOnlineAcc->FindRoleOne(req.role_id());
        if (!pRoleOne)
        {
            LOG_ERR(req.role_id(), -1, "RoleOne not found, roleId:{}", req.role_id());
            iRetCode = -1;
            break;
        }

        bool needChangeLogic = false;
        NFOnlineRole* pOnlineRole = NFOnlineRoleService::GetOnlineRole(req.role_id());
        if (pOnlineRole)
        {
            LOG_DEBUG(req.role_id(), "Role Get Role, old logic svr id:{}, new logic svr id:{}", NFServerIDUtil::GetBusNameFromBusID(pOnlineRole->GetLogicSvrId()), NFServerIDUtil::GetBusNameFromBusID(packet.nSrcId));
            res.set_active_logic_svr_id(pOnlineRole->GetLogicSvrId());
            if (pOnlineRole->GetLogicSvrId() != (int)packet.nSrcId)
            {
                needChangeLogic = true;
            }
        }

        if (needChangeLogic == false)
        {
            if (pOnlineAcc->GetLoginTransTime() > 0)
            {
                iRetCode = ERR_CODE_ACC_ROLE_LOGINING;
                LOG_WARN(req.role_id(), ERR_CODE_ACC_ROLE_LOGINING, "Acc has Role is logining, roleId:{}", req.role_id());
                break;
            }

            pOnlineAcc->SetLoginTransTime(NF_ADJUST_TIMENOW());
            res.set_login_lock_id(pOnlineAcc->GetLoginTransTime());
        }

        pRoleOne->ToPb(res.mutable_role());
        pOnlineAcc->GetBagPage()->MakeCSData(res.mutable_storage_data());
    }
    while (false);

    res.set_result(iRetCode);
    FindModule<NFIServerMessageModule>()->SendTransToLogicServer(NF_ST_ONLINE_SERVER, packet.nSrcId, E_ONLINE2ZONE_GETROLE_RES, res, req.role_id(), 0, packet.nParam1);
    return 0;
}

int NFOnlinePlayerModule::ProcAccLoginErrRes(const proto_ff::Proto_Zone2OnLineLoginReq& req, int errCode, int transId, int fromBusId)
{
    proto_ff::Proto_OnLine2ZoneLoginRes res;
    res.set_zone_id(req.zone_id());
    res.set_player_uin(req.player_uin());
    res.set_result(errCode);

    FindModule<NFIServerMessageModule>()->SendTransToLogicServer(NF_ST_ONLINE_SERVER, fromBusId, E_ONLINE2ZONE_LOGIN_RES, res, req.player_uin(), 0, transId);
    return 0;
}

int NFOnlinePlayerModule::OnHandleLoginEndNtf(uint64_t unLinkId, NFDataPackage& packet)
{
    proto_ff::Proto_Zone2OnlineLoginEndNtf ntf;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, ntf);

    uint64_t roleId = ntf.role_id();
    NFOnlineAcc* pOnlineAcc = NFOnlineAccMgr::Instance()->FindOnlineAcc(ntf.zone_id(), ntf.player_uin());
    CHECK_NULL_WF(roleId, pOnlineAcc, "ZoneId:{} PlayerUin:{} Not Exist OnlineAcc", ntf.zone_id(), ntf.player_uin());

    if (pOnlineAcc->GetLoginTransTime() != ntf.login_lock_id())
    {
        LOG_ERR(roleId, -1, "LoginLockId Not Match, RoleId:{} OnlineAcc LoginLockId:{} Ntf LoginLockId:{}", roleId, pOnlineAcc->GetLoginTransTime(), ntf.login_lock_id());
        return 0;
    }

    pOnlineAcc->SetLoginTransTime(0);

    return 0;
}

int NFOnlinePlayerModule::OnHandleRoleRegisterNtf(uint64_t unLinkId, NFDataPackage& packet)
{
    proto_ff::Proto_SSOnlineRegNtf ntf;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, ntf);

    uint64_t roleId = ntf.data().role().role_id();
    NFOnlineAcc* pOnlineAcc = NFOnlineAccMgr::Instance()->FindOnlineAcc(ntf.data().zone_id(), ntf.data().player_uin());
    CHECK_NULL_WF(roleId, pOnlineAcc, "ZoneId:{} PlayerUin:{} Not Exist OnlineAcc", ntf.data().zone_id(), ntf.data().player_uin());

    pOnlineAcc->SyncLogin(packet.nSrcId, ntf.data().role(), true);
    return 0;
}

int NFOnlinePlayerModule::OnHandleRoleSyncNtf(uint64_t unLinkId, NFDataPackage& packet)
{
    proto_ff::Proto_SSOnlineSyncNtf ntf;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, ntf);

    for (int i = 0; i < (int)ntf.data_size(); i++)
    {
        ProcRoleSyncNtf(packet.nSrcId, ntf.data(i));
    }
    return 0;
}

int NFOnlinePlayerModule::ProcRoleSyncNtf(int logicSvrId, const proto_ff::Proto_SSOnlineRoleCache& roleCache)
{
    uint64_t roleId = roleCache.role().role_id();
    NFOnlineAcc* pOnlineAcc = NFOnlineAccMgr::Instance()->FindOnlineAcc(roleCache.zone_id(), roleCache.player_uin());
    CHECK_NULL_WF(roleId, pOnlineAcc, "ZoneId:{} PlayerUin:{} Not Exist OnlineAcc", roleCache.zone_id(), roleCache.player_uin());

    pOnlineAcc->SyncLogin(logicSvrId, roleCache.role(), false);
    return 0;
}

int NFOnlinePlayerModule::OnHandleRoleExitNtf(uint64_t unLinkId, NFDataPackage& packet)
{
    proto_ff::Proto_SSOnlineExitNtf ntf;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, ntf);

    uint64_t roleId = ntf.role_id();
    NFOnlineAcc* pOnlineAcc = NFOnlineAccMgr::Instance()->FindOnlineAcc(ntf.zone_id(), ntf.player_uin());
    CHECK_NULL_WF(roleId, pOnlineAcc, "ZoneId:{} PlayerUin:{} Not Exist OnlineAcc", ntf.zone_id(), ntf.player_uin());

    if (roleId > 0)
    {
        NFOnlineRole* pOnlineRole = NFOnlineRoleService::GetOnlineRole(roleId);
        if (pOnlineRole)
        {
            if (pOnlineRole->GetLogicSvrId() != (int)packet.nSrcId)
            {
                LOG_ERR(roleId, -1, "Role LogicSvrId Not Match, RoleId:{} OnlineRole LogicSvrId:{} Ntf LogicSvrId:{}", roleId, pOnlineRole->GetLogicSvrId(), packet.nSrcId);
            }
        }
    }

    NFOnlineAccMgr::Instance()->TryDeleteOnlineAcc(pOnlineAcc, packet.nSrcId, roleId);

    LOG_INFO(roleId, "Role Exit, RoleId:{} ZoneId:{} PlayerUin:{}", roleId, ntf.zone_id(), ntf.player_uin());
    return 0;
}

int NFOnlinePlayerModule::OnHandleRoleArrangeBag(uint64_t unLinkId, NFDataPackage& packet)
{
    uint64_t roleId = packet.nModKey;
    proto_ff::Proto_OnlineToLogicArrageBagRsp respond;
    respond.set_result(0);
    do
    {
        NFOnlineRole* pOnlineRole = NFOnlineRoleService::GetOnlineRole(roleId);
        CHECK_NULL_BREAK_WF(roleId, pOnlineRole, "RoleId:{} Not Exist OnlineRole", roleId);

        NFOnlineAcc* pOnlineAcc = NFOnlineAccMgr::Instance()->FindOnlineAcc(pOnlineRole->GetZoneId(), pOnlineRole->GetUin());
        CHECK_NULL_BREAK_WF(roleId, pOnlineAcc, "ZoneId:{} PlayerUin:{} Not Exist OnlineAcc", pOnlineRole->GetZoneId(), pOnlineRole->GetUin());

        pOnlineAcc->GetBagPage()->Sort();
        auto pRsp = respond.mutable_rsp();
        pRsp->set_storage_page(EN_BPT_STORAGE);
        pOnlineAcc->GetBagPage()->MakeGridCSData(pRsp->mutable_grid_list());

        pOnlineAcc->BroadCast(E_SS_ONLINE_ROLE_ARRANGE_BAG, respond);
        return 0;
    } while (false);

    respond.set_result(-1);
    FindModule<NFIServerMessageModule>()->SendTransToLogicServer(NF_ST_ONLINE_SERVER, packet.nSrcId, E_SS_ONLINE_ROLE_ARRANGE_BAG, respond, roleId);
    return 0;
}

int NFOnlinePlayerModule::OnHandleRoleBuyBagGridPre(uint64_t unLinkId, NFDataPackage& packet)
{
    proto_ff::Proto_CSBuyBagGridInfo xData;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, xData);

    uint64_t roleId = packet.nModKey;
    proto_ff::Proto_OnlineToLogicBuyBagGridPreRsp respond;
    respond.set_result(0);
    int iRetCode = -1;

    do
    {
        auto pBagDesc = BagDesc::Instance()->GetDescByTypeTimes(xData.page(), xData.times());
        CHECK_NULL_BREAK_WF(roleId, pBagDesc, "page:{} times:{}", xData.page(), xData.times());

        NFOnlineRole* pOnlineRole = NFOnlineRoleService::GetOnlineRole(roleId);
        CHECK_NULL_BREAK_WF(roleId, pOnlineRole, "RoleId:{} Not Exist OnlineRole", roleId);

        NFOnlineAcc* pOnlineAcc = NFOnlineAccMgr::Instance()->FindOnlineAcc(pOnlineRole->GetZoneId(), pOnlineRole->GetUin());
        CHECK_NULL_BREAK_WF(roleId, pOnlineAcc, "ZoneId:{} PlayerUin:{} Not Exist OnlineAcc", pOnlineRole->GetZoneId(), pOnlineRole->GetUin());

        auto pPage = pOnlineAcc->GetBagPage();
        CHECK_NULL_BREAK_WF(roleId, pPage, "RoleId:{} Not Exist OnlineRole", roleId);

        if (pBagDesc->times != pPage->GetOpenGridTimes() + 1)
        {
            LOG_ERR(roleId, -1, "param of times error:{} {}", pBagDesc->times, pPage->GetOpenGridTimes());
            iRetCode = ERR_CODE_INVALID_REQ_PARAM;
            break;
        }

        if (pPage->GetCapacity() + pBagDesc->grids > pPage->GetMaxSize())
        {
            LOG_ERR(roleId, -1,  "RoleId:{} Bag:{} Check Add Capacity:{} failed", roleId, xData.page(), pBagDesc->grids);
            break;
        }

        FindModule<NFIServerMessageModule>()->SendTransToLogicServer(NF_ST_ONLINE_SERVER, packet.nSrcId, E_SS_ONLINE_ROLE_BUY_BAG_GRID_PRE, respond, roleId, 0, packet.nParam1);
        return 0;
    } while (false);

    respond.set_result(iRetCode);
    FindModule<NFIServerMessageModule>()->SendTransToLogicServer(NF_ST_ONLINE_SERVER, packet.nSrcId, E_SS_ONLINE_ROLE_BUY_BAG_GRID_PRE, respond, roleId, 0, packet.nParam1);
    return 0;
}

int NFOnlinePlayerModule::OnHandleRoleBuyBagGrid(uint64_t unLinkId, NFDataPackage& packet)
{
    proto_ff::Proto_OnlineToLogicBuyBagGridReq xData;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, xData);

    uint64_t roleId = packet.nModKey;
    proto_ff::Proto_OnlineToLogicBuyBagGridRsp respond;
    respond.set_result(0);
    int iRetCode = -1;

    do
    {
        auto pBagDesc = BagDesc::Instance()->GetDescByTypeTimes(xData.info().page(), xData.info().times());
        CHECK_NULL_BREAK_WF(roleId, pBagDesc, "page:{} times:{}", xData.info().page(), xData.info().times());

        NFOnlineRole* pOnlineRole = NFOnlineRoleService::GetOnlineRole(roleId);
        CHECK_NULL_BREAK_WF(roleId, pOnlineRole, "RoleId:{} Not Exist OnlineRole", roleId);

        NFOnlineAcc* pOnlineAcc = NFOnlineAccMgr::Instance()->FindOnlineAcc(pOnlineRole->GetZoneId(), pOnlineRole->GetUin());
        CHECK_NULL_BREAK_WF(roleId, pOnlineAcc, "ZoneId:{} PlayerUin:{} Not Exist OnlineAcc", pOnlineRole->GetZoneId(), pOnlineRole->GetUin());

        auto pPage = pOnlineAcc->GetBagPage();
        CHECK_NULL_BREAK_WF(roleId, pPage, "RoleId:{} Not Exist OnlineRole", roleId);

        if (pBagDesc->times != pPage->GetOpenGridTimes() + 1)
        {
            LOG_ERR(roleId, -1, "param of times error:{} {}", pBagDesc->times, pPage->GetOpenGridTimes());
            iRetCode = ERR_CODE_INVALID_REQ_PARAM;
            break;
        }

        int iOldCapacity = 0;
        int iNewCapacity = 0;
        iRetCode = pPage->AddCapacity(pBagDesc->grids, &iOldCapacity, &iNewCapacity);
        CHECK_ERR_BREAK_WF(roleId, iRetCode, "bag:{} AddCapacity:{} failed", xData.info().page(), pBagDesc->grids);

        auto pRsp = respond.mutable_info();
        pRsp->set_page(xData.info().page());
        pRsp->set_times(xData.info().times());
        pRsp->set_total_grid(iNewCapacity);
        FindModule<NFIServerMessageModule>()->SendTransToLogicServer(NF_ST_ONLINE_SERVER, packet.nSrcId, E_SS_ONLINE_ROLE_BUY_BAG_GRID, respond, roleId, 0, packet.nParam1);

        pOnlineAcc->BroadCast(E_SS_ONLINE_ROLE_BUY_BAG_GRID, respond);
        return 0;
    } while (false);

    respond.set_result(iRetCode);
    FindModule<NFIServerMessageModule>()->SendTransToLogicServer(NF_ST_ONLINE_SERVER, packet.nSrcId, E_SS_ONLINE_ROLE_BUY_BAG_GRID, respond, roleId, 0, packet.nParam1);
    return 0;
}

int NFOnlinePlayerModule::OnHandleRoleStorageSavePre(uint64_t unLinkId, NFDataPackage& packet)
{
    proto_ff::Proto_OnlineToLogicStorageSavePreReq xData;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, xData);

    uint64_t roleId = packet.nModKey;
    proto_ff::Proto_OnlineToLogicStorageSavePreRsp respond;
    respond.set_result(0);
    int iRetCode = -1;

    do
    {
        NFOnlineRole* pOnlineRole = NFOnlineRoleService::GetOnlineRole(roleId);
        CHECK_NULL_BREAK_WF(roleId, pOnlineRole, "RoleId:{} Not Exist OnlineRole", roleId);

        NFOnlineAcc* pOnlineAcc = NFOnlineAccMgr::Instance()->FindOnlineAcc(pOnlineRole->GetZoneId(), pOnlineRole->GetUin());
        CHECK_NULL_BREAK_WF(roleId, pOnlineAcc, "ZoneId:{} PlayerUin:{} Not Exist OnlineAcc", pOnlineRole->GetZoneId(), pOnlineRole->GetUin());

        NFGridItem addItem;
        addItem.FromPb(xData.save_item());

        NFStorageBagOpMgr opMgr(pOnlineAcc, EN_ICR_STORAGE_OP, false);
        iRetCode = opMgr.AddToBag(addItem, addItem.GetNumber());
        CHECK_ERR_BREAK_WF(roleId, iRetCode, "AddToBag:{} failed", addItem.ShortDebugString());

        FindModule<NFIServerMessageModule>()->SendTransToLogicServer(NF_ST_ONLINE_SERVER, packet.nSrcId, E_SS_ONLINE_ROLE_STORAGE_SAVE_PRE, respond, roleId, 0, packet.nParam1);
        return 0;
    } while (false);

    respond.set_result(iRetCode);
    FindModule<NFIServerMessageModule>()->SendTransToLogicServer(NF_ST_ONLINE_SERVER, packet.nSrcId, E_SS_ONLINE_ROLE_STORAGE_SAVE_PRE, respond, roleId, 0, packet.nParam1);
    return 0;
}

int NFOnlinePlayerModule::OnHandleRoleStorageSave(uint64_t unLinkId, NFDataPackage& packet)
{
    proto_ff::Proto_OnlineToLogicStorageSaveReq xData;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, xData);

    uint64_t roleId = packet.nModKey;
    proto_ff::Proto_OnlineToLogicStorageSaveRsp respond;
    respond.set_result(0);
    int iRetCode = -1;

    do
    {
        NFOnlineRole* pOnlineRole = NFOnlineRoleService::GetOnlineRole(roleId);
        CHECK_NULL_BREAK_WF(roleId, pOnlineRole, "RoleId:{} Not Exist OnlineRole", roleId);

        NFOnlineAcc* pOnlineAcc = NFOnlineAccMgr::Instance()->FindOnlineAcc(pOnlineRole->GetZoneId(), pOnlineRole->GetUin());
        CHECK_NULL_BREAK_WF(roleId, pOnlineAcc, "ZoneId:{} PlayerUin:{} Not Exist OnlineAcc", pOnlineRole->GetZoneId(), pOnlineRole->GetUin());

        NFGridItem addItem;
        addItem.FromPb(xData.save_item());

        NFStorageBagOpMgr opMgr(pOnlineAcc, EN_ICR_STORAGE_OP, true);
        iRetCode = opMgr.AddToBag(addItem, addItem.GetNumber());
        CHECK_ERR_BREAK_WF(roleId, iRetCode, "AddToBag:{} failed", addItem.ShortDebugString());
        iRetCode = opMgr.Commit(true);
        CHECK_ERR_BREAK_WF(roleId, iRetCode, "Commit:{} failed", addItem.ShortDebugString());

        FindModule<NFIServerMessageModule>()->SendTransToLogicServer(NF_ST_ONLINE_SERVER, packet.nSrcId, E_SS_ONLINE_ROLE_STORAGE_SAVE, respond, roleId, 0, packet.nParam1);

        return 0;
    } while (false);

    respond.set_result(iRetCode);
    FindModule<NFIServerMessageModule>()->SendTransToLogicServer(NF_ST_ONLINE_SERVER, packet.nSrcId, E_SS_ONLINE_ROLE_STORAGE_SAVE, respond, roleId, 0, packet.nParam1);
    return 0;
}

int NFOnlinePlayerModule::OnHandleRolePickFromStoragePre(uint64_t unLinkId, NFDataPackage& packet)
{
    proto_ff::Proto_OnlineToLogicPickFromStoragePreReq xData;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, xData);

    uint64_t roleId = packet.nModKey;
    proto_ff::Proto_OnlineToLogicPickFromStoragePreRsp respond;
    respond.set_result(0);
    int iRetCode = -1;

    do
    {
        NFOnlineRole* pOnlineRole = NFOnlineRoleService::GetOnlineRole(roleId);
        CHECK_NULL_BREAK_WF(roleId, pOnlineRole, "RoleId:{} Not Exist OnlineRole", roleId);

        NFOnlineAcc* pOnlineAcc = NFOnlineAccMgr::Instance()->FindOnlineAcc(pOnlineRole->GetZoneId(), pOnlineRole->GetUin());
        CHECK_NULL_BREAK_WF(roleId, pOnlineAcc, "ZoneId:{} PlayerUin:{} Not Exist OnlineAcc", pOnlineRole->GetZoneId(), pOnlineRole->GetUin());

        NFStorageBagOpMgr opMgr(pOnlineAcc, EN_ICR_STORAGE_OP, false);
        auto pOp = opMgr.GetBagPageOpByBagType(EN_BPT_STORAGE);
        CHECK_NULL_BREAK_WF(roleId, pOp, "GetBagPageOpByBagType:{} failed", EN_BPT_STORAGE);
        auto pGrid = pOp->GetGrid(xData.req().grid_index());
        CHECK_NULL_BREAK_WF(roleId, pGrid, "GetGrid:{} failed", xData.req().grid_index());

        if ((int)pGrid->GetItemID() != xData.req().item_id() || pGrid->GetUUID() != xData.req().uuid())
        {
            iRetCode = ERR_CODE_INVALID_REQ_PARAM;
            LOG_ERR(roleId, iRetCode, "param invalid req:{}", xData.req().DebugString());
            break;
        }

        *respond.mutable_req() = xData.req();
        NFGridItem stItem = pGrid->GetItem();
        stItem.SetNumber(xData.req().item_num());

        iRetCode = opMgr.DelItemByGridIndex(EN_BPT_STORAGE, xData.req().grid_index(), xData.req().item_num());
        CHECK_ERR_BREAK_WF(roleId, iRetCode, "DelItemByGridIndex failed, grid_index:{} item_num:{}", xData.req().grid_index(), xData.req().item_num());

        auto pDesc = ItemDesc::Instance()->GetDesc(stItem.GetItemID());
        CHECK_NULL_BREAK_WF(roleId, pDesc, "ItemID:{} Not Exist ItemDesc", stItem.GetItemID());
        if (pDesc->bind_role_after_pick)
        {
            stItem.SetBind(true);
            stItem.SetTradeCoolDown(0);
        }
        stItem.ToPb(respond.mutable_item());
        FindModule<NFIServerMessageModule>()->SendTransToLogicServer(NF_ST_ONLINE_SERVER, packet.nSrcId, E_SS_ONLINE_ROLE_PICK_FROM_STORAGE_PRE, respond, roleId, 0, packet.nParam1);
        return 0;
    } while (false);

    respond.set_result(iRetCode);
    FindModule<NFIServerMessageModule>()->SendTransToLogicServer(NF_ST_ONLINE_SERVER, packet.nSrcId, E_SS_ONLINE_ROLE_PICK_FROM_STORAGE_PRE, respond, roleId, 0, packet.nParam1);
    return 0;
}

int NFOnlinePlayerModule::OnHandleRolePickFromStorage(uint64_t unLinkId, NFDataPackage& packet)
{
    proto_ff::Proto_OnlineToLogicPickFromStorageReq xData;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, xData);

    uint64_t roleId = packet.nModKey;
    proto_ff::Proto_OnlineToLogicPickFromStorageRsp respond;
    respond.set_result(0);
    int iRetCode = -1;

    do
    {
        NFOnlineRole* pOnlineRole = NFOnlineRoleService::GetOnlineRole(roleId);
        CHECK_NULL_BREAK_WF(roleId, pOnlineRole, "RoleId:{} Not Exist OnlineRole", roleId);

        NFOnlineAcc* pOnlineAcc = NFOnlineAccMgr::Instance()->FindOnlineAcc(pOnlineRole->GetZoneId(), pOnlineRole->GetUin());
        CHECK_NULL_BREAK_WF(roleId, pOnlineAcc, "ZoneId:{} PlayerUin:{} Not Exist OnlineAcc", pOnlineRole->GetZoneId(), pOnlineRole->GetUin());

        NFStorageBagOpMgr opMgr(pOnlineAcc, EN_ICR_STORAGE_OP, true);
        auto pOp = opMgr.GetBagPageOpByBagType(EN_BPT_STORAGE);
        CHECK_NULL_BREAK_WF(roleId, pOp, "GetBagPageOpByBagType:{} failed", EN_BPT_STORAGE);
        auto pGrid = pOp->GetGrid(xData.req().grid_index());
        CHECK_NULL_BREAK_WF(roleId, pGrid, "GetGrid:{} failed", xData.req().grid_index());

        if ((int)pGrid->GetItemID() != xData.req().item_id() || pGrid->GetUUID() != xData.req().uuid())
        {
            iRetCode = ERR_CODE_INVALID_REQ_PARAM;
            LOG_ERR(roleId, iRetCode, "param invalid req:{}", xData.req().DebugString());
            break;
        }

        iRetCode = opMgr.DelItemByGridIndex(EN_BPT_STORAGE, xData.req().grid_index(), xData.req().item_num());
        CHECK_ERR_BREAK_WF(roleId, iRetCode, "DelItemByGridIndex failed, grid_index:{} item_num:{}", xData.req().grid_index(), xData.req().item_num());

        iRetCode = opMgr.Commit(true);
        CHECK_ERR_BREAK_WF(roleId, iRetCode, "Commit:{} failed", xData.req().DebugString());

        FindModule<NFIServerMessageModule>()->SendTransToLogicServer(NF_ST_ONLINE_SERVER, packet.nSrcId, E_SS_ONLINE_ROLE_PICK_FROM_STORAGE, respond, roleId, 0, packet.nParam1);

        return 0;
    } while (false);

    respond.set_result(iRetCode);
    FindModule<NFIServerMessageModule>()->SendTransToLogicServer(NF_ST_ONLINE_SERVER, packet.nSrcId, E_SS_ONLINE_ROLE_PICK_FROM_STORAGE, respond, roleId, 0, packet.nParam1);
    return 0;
}
